<?php

namespace addons\facrm\library\cloudcall\engine;


use fast\Http;

/**
 * tycc100.com
 * @author amplam 122795200@qq.com
 */
class Moor extends Server
{
    protected $httpwww="https://apis.7moor.com";
    /**
     * 测试的账号
     * @var array|string[]
     */
    protected $config=[
        'acount_id'=>'',
        'secret'=>'',
    ];

    /**
     * 构造方法
     * @param $config
     */
    public function __construct($config = array())
    {
        $this->config =$config? $config:$this->config;
        if (isset($this->config['httpwww'])&&$this->config['httpwww'])
            $this->httpwww=$this->config['httpwww'];
    }

    /**
     * 拨打
     * @param $config
     * @param $data Exten
     * @param array $extend 扩展参数
     * @return bool
     */
    public function call($data=array(),$extend=array()){
        if (!isset($data['exten'])||!$data['exten']){
            $this->error='联系方式不能为空';
            return  false;
        }
        if (!isset($data['from_exten'])||!$data['from_exten']){
            $this->error='坐席不能为空';
            return  false;
        }
        $result=$this->dialout($data,$extend);
        $result=json_decode($result,true);
        if (isset($result['Succeed'])&&$result['Succeed']){
            return  $result;
        }
        $this->error=isset($result['Message'])?$result['Message']:$result['message'];

        return  false;
    }

    /**
     * 外呼接口
     * @return bool|string
     */
    public function dialout($data,$extend){
        $strtime=datetime(time(),'YmdHis');
        $sig=$this->getSig($strtime);
        $send_data=array(
            'FromExten'=>$data['from_exten'],//员工坐席
            'Exten'=>$data['exten'],//第一个电话号码[客户电话]
			'ExtenType'=>$data['exten_type'],//Local/sip/gateway外呼时强制坐席使用该接听方式进行外呼。Local为“手机”,”gateway为“语音网关”
        );
        $header = [
            'Content-Type: application/json; charset=utf-8',
            'Authorization: '.$this->getAuthorization($strtime),
            'Content-Length: ' . strlen(json_encode($send_data)),
        ];

        $url=$this->httpwww."/v20160818/call/dialout/{$this->config['acount_id']}?sig=".$sig;
        return self::curl_post_content($url, json_encode($send_data), $header);
    }

    /**
     * 签入或签出
     */
    public function signInOrOut($data){

        $strtime=datetime(time(),'YmdHis');
        $sig=$this->getSig($strtime);
        $send_data=array(
            'sign'=>isset($data['sign'])?$data['sign']:'SignIn',//SignIn / SignOut
            'exten'=>$data['exten'],//座席号
            'ExtenType'=>$data['exten_type'],//Local/sip/gateway外呼时强制坐席使用该接听方式进行外呼。Local为“手机”,”gateway为“语音网关”
        );
        $header = [
            'Content-Type: application/json; charset=utf-8',
            'Authorization: '.$this->getAuthorization($strtime),
            'Content-Length: ' . strlen(json_encode($send_data)),
        ];
        $url=$this->httpwww."/v20160818/account/SignInOrOut/{$this->config['acount_id']}?sig=".$sig;
        return self::curl_post_content($url, json_encode($send_data), $header);


    }

    /**
     * 获取通话记录
     */
    public function getCallRecord($data){
        if (!isset($data['beginTime'])){
            $data['beginTime'] =datetime( time()-(86400*1), 'Y-m-d H:i:s') ;//开始时间
        }
        if (!isset($data['endTime'])){
            $data['endTime'] =datetime( time(), 'Y-m-d H:i:s');//结束时间
        }
        $strtime=datetime(time(),'YmdHis');
        $sig=$this->getSig($strtime);


        $send_data=array(
            'beginTime'=> $data['beginTime'],
            'endTime'=>$data['endTime'],
            'getAll'=>true,
        );
        isset($data['callNo'])?$send_data['callNo']=$data['callNo']:'';//主叫号码
        isset($data['calledNo'])?$send_data['calledNo']=$data['calledNo']:'';//被叫号码

        $header = [
            'Content-Type: application/json; charset=utf-8',
            'Authorization: '.$this->getAuthorization($strtime),
            'Content-Length: ' . strlen(json_encode($send_data)),
        ];
        $url=$this->httpwww."/v20180426/cdr/getCCCdr/{$this->config['acount_id']}?sig=".$sig;
        return self::curl_post_content($url, json_encode($send_data), $header);
    }



    /**
     * 获取报表 TODO 看文档报表不存在先不做，有时间问问
     */
    public function statistics($data=array()){


        $strtime=datetime(time(),'YmdHis');
        $sig=$this->getSig($strtime);

        $send_data=array(
            'account'=>$this->config['acount_id'],
            'TimeType'=>'day',
        );
        $header = [
            'Content-Type: application/json; charset=utf-8',
            'Authorization: '.$this->getAuthorization($strtime),
            'Content-Length: ' . strlen(json_encode($send_data)),
        ];
        $url=$this->httpwww."/v20180426/callReport/openAgent/{$this->config['acount_id']}?sig=".$sig;
        return self::curl_post_content($url, json_encode($send_data), $header);
    }




    protected function getAuthorization($strtime){

       return base64_encode(  $this->config['acount_id'].":".$strtime);
    }
    protected function getSig($strtime){
        //sig的值为 32位大写MD5加密 （帐号Id + 帐号APISecret +时间戳）
        return strtoupper( md5($this->config['acount_id'].$this->config['secret'].$strtime));

    }
    public static function curl_post_content($url, $data = null, $header = [])
    {
        $ch = curl_init();
        if (substr_count($url, 'https://') > 0) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        if (!empty($data)) {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        }
        if (!empty($header)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }
        curl_setopt($ch, CURLOPT_TIMEOUT, 15);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
        $res = curl_exec($ch);
        if (curl_errno($ch)) {
            $res = false;
        }
        curl_close($ch);

        return $res;
    }



    /**
     * 通话结束回调
     */
    public function back(){
        $params = request()->request();
        \think\Log::write($params,"_________callcack________");

        $CallNo=isset($params['CallNo'])?$params['CallNo']:"";
        if (strlen($CallNo)<6){
            $CallNo=isset($params['caller'])&&$params['caller']?$params['caller']:$CallNo;
        }
        //agentCallout这个参数就是坐席外呼
        $CallType=isset($params['agentCallout'])?$params['agentCallout']:"";
        $CallType=!$CallType&&isset($params['CallType']) ? $params['CallType'] : $CallType;


        $params = [
            'CallNo' => $CallNo,//主叫号码
            'CalledNo' => isset($params['CalledNo']) ? $params['CalledNo'] : '',//被叫号码
            'CallSheetID' => isset($params['CallSheetID']) ? $params['CallSheetID'] : '',//通话记录ID,CallSheetID 是这条通话记录再DB中的唯一id
            //通话类型：dialout外呼通话,normal普通来电,transfer转接电话,dialTransfer外呼转接
            'CallType' => $CallType,
            '' => isset($params['Ring']) ? $params['Ring'] : '',//通话振铃时间（话务进入呼叫中心系统的时间）
            //通话接通时间（呼入是按座席接起的时间,外呼按客户接起的时间,如果没接听的话为空）
            'Begin' => isset($params['Begin']) ? $params['Begin'] : '',
            'End' => isset($params['End']) ? $params['End'] : '',//通话结束时间
            '' => isset($params['QueueTime']) ? $params['QueueTime'] : '',//来电进入技能组时间
            'Agent' => isset($params['Agent']) ? $params['Agent'] : '',//处理坐席的工号
            'Exten' => isset($params['Exten']) ? $params['Exten'] : '',//处理坐席的工号,历史原因该字段与Agent相同
            '' => isset($params['AgentName']) ? $params['AgentName'] : '',//处理坐席的姓名
            //接听状态：dealing（已接）,notDeal（振铃未接听）,leak（ivr放弃）,queueLeak（排队放弃）,blackList（黑名单）,
            //voicemail（留言）,limit（并发限制）
            'State' => isset($params['State']) ? $params['State'] : '',
            'CallState' => isset($params['CallState']) ? $params['CallState'] : '',//事件状态：Ring, Ringing, Link, Hangup(Unlink也当成Hangup处理)
            'ActionID' => isset($params['ActionID']) ? $params['ActionID'] : '',//通过外呼接口调用时,该字段会保存请求的actionID,其它情况下该字段为空
            //通过调用webcall接口,该字段会保存请求的actionID,其它情况下该字段为空
            '' => isset($params['WebcallActionID']) ? $params['WebcallActionID'] : '',
            //通话录音文件名：用户要访问录音时,在该文件名前面加上服务路径即可,如：FileServer/RecordFile
            'RecordFile' => isset($params['RecordFile']) ? $params['RecordFile'] : '',
            //通过FileServer中指定的地址加上RecordFile的值可以获取录音
            'FileServer' => isset($params['FileServer']) ? $params['FileServer'] : '',
            '' => isset($params['Province']) ? $params['Province'] : '',
            '' => isset($params['District']) ? $params['District'] : '',
            '' => isset($params['CallID']) ? $params['CallID'] : '',
            //账户编号字段,默认不推送有需求的客户对接时联系云呼技术支持人员进行开通
            'AccountId' => isset($params['AccountId']) ? $params['AccountId'] : '',
            'Province' => isset($params['Province']) ? $params['Province'] : '',//省份
            'District' => isset($params['District']) ? $params['District'] : '',//城市
            'CdrVar' => isset($params['CdrVar']) ? $params['CdrVar'] : '',//CdrVar
        ];

        if ($params['CallState'] != "Hangup" && $params['CallState'] != "Unlink") {
            return $this->msg("CallState error");
        }
        if ($params['CallSheetID']==""){
            return $this->msg("CallSheetID null");
        }
        if ($params['Agent']==""&&$params['Exten']==""){
            return $this->msg("坐席空");
        }
        $attribution="";
        if ($params['Province']){
            $attribution=$params['Province'].($params['District']?','.$params['District']:"");
        }

        $cloudcallLog = new \app\admin\model\facrm\CloudcallLog();
        if ($params['CdrVar']&&!is_numeric($params['CdrVar'])){
            $params['CallSheetID']=$params['CdrVar'];
            $params['ActionID']=$params['ActionID']?$params['ActionID']:$params['CdrVar'];
        }


        if ($params['ActionID']) {
            $log = $cloudcallLog->where('action_id', $params['ActionID'])->where('status', 0)->find();
            if ($log) {
                $log->called_no = $params['CalledNo'];
                $log->call_no = $params['CallNo'];
                $log->status = $params['State'] == 'dealing' ? 1 : -1;
                $log->record_file = $params['FileServer'] . '/' . $params['RecordFile'];
                $log->call_time_length = $this->callTimeLenth($params['Begin'], $params['End']);
                //$log->attribution=$attribution;
                $log->save();
                return $this->msg("200",$log->toArray());
            }
        }
        //保存通话记录  软件上手拨打的
        if (isset($params['CallSheetID']) && $cloudcallLog->where('action_id', $params['CallSheetID'])->count() <= 0) {
            $insert_data=[
                'admin_id' => 0,
                'cloud' => 'Moor',
                'from_exten' => $params['Agent'] ? $params['Agent'] : $params['Exten'],
                'exten_type' => $params['CallType'],//临时用作
                'name' => "",
                'source' =>isset($params['source'])?$params['source']:"",
                'source_id' => isset($params['source_id'])?$params['source_id']:0,
                'status' => $params['State'] == 'dealing' ? 1 : -1,
                'call_no' => $params['CallNo'] ? $params['CallNo'] : '',
                'called_no' => $params['CalledNo'] ? $params['CalledNo'] : "",
                'call_time_length' => $this->callTimeLenth($params['Begin'], $params['End']),
                'record_file' => $params['FileServer'] . '/' . $params['RecordFile'],
                'action_id' => $params['CallSheetID'],
                //'attribution'=>$attribution
            ];
            $cloudcallLog->isUpdate(false)->save($insert_data);
            return $this->msg("200",$insert_data);
        }
        return $this->msg("err");
    }

    /**
     * 输出内容
     */
    protected function msg($msg = "200",$log=array())
    {
        echo $msg;
        hook('cloudcall_back',$log);//
        exit();
    }

    /**
     * 获取通话时长
     * @param $start
     * @param $end
     * @return bool|string
     */
    protected function callTimeLenth($start, $end)
    {
        if (!$start || !$end) return 0;
        $start = is_numeric($start) ?: strtotime($start);
        $end = is_numeric($end) ? $end : strtotime($end);

        return \fast\Date::span($start, $end, 'seconds');
    }



}